package com.dji.GSDemo.GaodeMap.UploadPicture;

import android.content.Context;

import com.dji.GSDemo.GaodeMap.MApplication;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import dji.common.camera.SettingsDefinitions;
import dji.common.error.DJIError;
import dji.common.util.CommonCallbacks;
import dji.sdk.base.BaseProduct;
import dji.sdk.camera.Camera;
import dji.sdk.media.DownloadListener;
import dji.sdk.media.MediaFile;
import dji.sdk.media.MediaManager;
import dji.sdk.sdkmanager.DJISDKManager;
import dji.thirdparty.okhttp3.Call;
import dji.thirdparty.okhttp3.Callback;
import dji.thirdparty.okhttp3.MediaType;
import dji.thirdparty.okhttp3.MultipartBody;
import dji.thirdparty.okhttp3.OkHttpClient;
import dji.thirdparty.okhttp3.Request;
import dji.thirdparty.okhttp3.RequestBody;
import dji.thirdparty.okhttp3.Response;

public class UAVUploadPicture {

    List<UAVPictureUploadListener> listeners = new ArrayList<>();
    // 媒体管理器
    private MediaManager mMediaManager;
    private Context context = MApplication.getContext();
    private String ipAddr;
    private int downloadingPictureCount = 0;

    private static class Singleton {
        private static final UAVUploadPicture instance = new UAVUploadPicture();
    }

    private UAVUploadPicture() {
    }

    public static UAVUploadPicture getInstance() {
        return Singleton.instance;
    }

    public void setContext(Context acontext) {
        context = acontext;
    }

    public void setIP(String aIP) {
        ipAddr = aIP;
    }

    public int download_all() {
        if (ipAddr == null) {
            showToast("in UAVUploadPicture context or ip has not been set");
            return 0;
        }
        List<String> newFiles = initMediaManager();
        Thread unsetthread = new unsetThread(newFiles.size());
        unsetthread.start();
        return newFiles.size();
    }

    public int getDownloadingPictureCount() {
        return downloadingPictureCount;
    }

    private int targetPicNum = 0;

    private class unsetThread extends Thread {
        int size;

        public unsetThread(int targetSize) {
            size = targetSize;
        }

        @Override
        public void run() {
            while (true) {
                if (targetPicNum == 2) {
                    while (true) {
                        // 当下载个数等于检查出来的所有文件的个数时，停止下载，切换摄像机模式。
                        if (targetPicNum >= size) {
                            unsetMediaManager();
                            targetPicNum = 0;
                            break;
                        }
                    }
                }
            }
        }
    }

    public void addListener(UAVPictureUploadListener obj){
        if (listeners == null) {
            throw new NullPointerException();
        } else {
            if (!listeners.contains(obj)) {
                listeners.add(obj);
            }
        }
    }

    public void removeListener(UAVPictureUploadListener obj) {
        if (listeners == null) {
            throw new NullPointerException();
        } else {
            listeners.remove(obj);
        }
    }


    // 下载媒体文件
    private void download(MediaFile mMediaFile) {
        // 设置下载位置
        File downloadDir = new File(context.getExternalFilesDir(null) + "/media/");
        downloadingPictureCount += 1;
        // 开始下载文件
        mMediaFile.fetchFileData(downloadDir, null, new DownloadListener<String>() {
            @Override
            public void onFailure(DJIError error) {
                showToast("文件下载失败!");
                decreaseDownloadingPictureCount();
            }

            @Override
            public void onProgress(long total, long current) {
            }

            @Override
            public void onRateUpdate(final long total, final long current, long persize) {
            }

            @Override
            public void onStart() {
            }

            @Override
            public void onSuccess(String filePath) {
                targetPicNum = targetPicNum + 1;
                showToast(mMediaFile.getFileName() + "文件下载成功,下载位置为:" + filePath);
                List<String> newfiles = new ArrayList<String>();
                newfiles.add(mMediaFile.getFileName());
                send_picture_to_GCS_by_http(newfiles);
                decreaseDownloadingPictureCount();
            }

            @Override
            public void onRealtimeDataUpdate(byte[] bytes, long l, boolean b) {

            }
        });
    }

    // 功能（从媒体管理器中取出文件列表）需要的一个全局变量：指示getLastMediaList()中的回调函数是否把所有文件名存入这个列表中。
    public boolean isGetMediaList = false;
    // 功能（从媒体管理器中取出文件列表）需要的一个全局变量：getLastMediaList()中的回调函数中得到文件名存入这个列表中。
    public List<String> oldFilesList = new ArrayList<String>();
    // 功能（从媒体管理器中取出文件列表）需要的一个函数：调用getLastMediaList()前把全局变量置isGetMediaList为false，把全局变量oldFilesList清空。
    public void prepareBeforeRun_getLastMediaList(){
        isGetMediaList = false;
        oldFilesList = new ArrayList<String>();
    }
    // 功能（从媒体管理器中取出文件列表）需要的一个函数：在一个回调函数中得到文件名列表。
    public boolean getLastMediaList() {
        Camera camera = getCamera();
        // 判断相机对象非空，且支持媒体下载模式
        if (camera == null) {
            showToast("相机对象获取错误!");
            return false;
        }
        if (!camera.isMediaDownloadModeSupported()) {
            showToast("当前相机不支持媒体下载模式!");
            return false;
        }
        // 获取媒体管理器
        mMediaManager = camera.getMediaManager();
        if (mMediaManager == null) {
            showToast("媒体管理器错误!");
            return false;
        }
        // 设置当前相机模式为媒体下载模式
        camera.setMode(SettingsDefinitions.CameraMode.MEDIA_DOWNLOAD, new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError djiError) {
                if (djiError != null) {
                    showToast("相机模式设置错误!" + djiError.getDescription());
                    return;
                }
                showToast("开始获取媒体列表!");
                // 开始获取媒体文件列表
                mMediaManager.refreshFileListOfStorageLocation(SettingsDefinitions.StorageLocation.SDCARD, new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onResult(DJIError djiError) {
                        if (djiError != null) {
                            showToast("获取媒体文件列表错误!" + djiError.getDescription());
                            return;
                        }
                        // 媒体文件列表
                        List<MediaFile> mediaFiles = mMediaManager.getSDCardFileListSnapshot();
                        int fileNum = mediaFiles.size();
                        showToast("有" + Integer.toString(fileNum) + "个文件");

                        for (int i = 0; i < fileNum; i++) {
                            oldFilesList.add(mediaFiles.get(i).getFileName());
                        }
                        isGetMediaList = true;
                        showToast("从SD卡中找到" + Integer.toString(oldFilesList.size()) + "个遗留文件");
                        unsetMediaManager();
                    }
                });

            }
        });
        return true;
    }

    private void decreaseDownloadingPictureCount(){
        if(downloadingPictureCount>0)
            downloadingPictureCount -= 1;
        if(downloadingPictureCount==0){
            for(UAVPictureUploadListener listener : listeners){
//                listener.onDownloadComplete();
            }
        }
    }

    // 初始化媒体管理器
    private List<String> initMediaManager() {
        List<String> newfiles = new ArrayList<String>();
        Camera camera = getCamera();
        // 判断相机对象非空，且支持媒体下载模式
        if (camera == null) {
            showToast("相机对象获取错误!");
            return newfiles;
        }
        if (!camera.isMediaDownloadModeSupported()) {
            showToast("当前相机不支持媒体下载模式!");
            return newfiles;
        }
        // 获取媒体管理器
        mMediaManager = camera.getMediaManager();
        if (mMediaManager == null) {
            showToast("媒体管理器错误!");
            return newfiles;
        }
        // 设置当前相机模式为媒体下载模式
        camera.setMode(SettingsDefinitions.CameraMode.MEDIA_DOWNLOAD, new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError djiError) {
                if (djiError != null) {
                    showToast("相机模式设置错误!" + djiError.getDescription());
                    return;
                }
                showToast("开始获取媒体列表!");
                // 开始获取媒体文件列表
                mMediaManager.refreshFileListOfStorageLocation(SettingsDefinitions.StorageLocation.SDCARD, new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onResult(DJIError djiError) {
                        if (djiError != null) {
                            showToast("获取媒体文件列表错误!" + djiError.getDescription());
                            return;
                        }
                        // 媒体文件列表
                        List<MediaFile> mediaFiles = mMediaManager.getSDCardFileListSnapshot();
                        int fileNum = mediaFiles.size();
                        showToast("有" + Integer.toString(fileNum) + "个文件");
                        File storeDir = new File(context.getExternalFilesDir(null) + "/media/");
                        if (!storeDir.exists()) {
                            storeDir.mkdirs();
                        }
                        String[] files = storeDir.list(); //files里只有文件名，没有文件的绝对路径。

                        int filesNum = files.length;
                        int downloadNum = 0;
                        for (int i = 0; i < fileNum; i++) {
                            boolean isNewFile = true;
                            for (int ifile = 0; ifile < filesNum; ifile++) {
                                if (mediaFiles.get(i).getFileName().equals(files[ifile])) {
                                    isNewFile = false;
                                    break;
                                }
                            }
                            if (isNewFile) {
                                if (mediaFiles.get(i).getFileName().substring(mediaFiles.get(i).getFileName().lastIndexOf(".")).equals(".jpg")) {
                                    downloadNum = downloadNum + 1;
                                    newfiles.add(mediaFiles.get(i).getFileName());
                                    Thread downloadFile = new downloadFileThread(mediaFiles.get(i));
                                    downloadFile.start();
                                }

                            }
                        }
                        showToast("有" + Integer.toString(downloadNum) + "个文件判定为要下载的文件");
//                        send_picture_to_GCS_by_http(newfiles);
//                        unsetMediaManager();
                    }
                });

            }
        });
        return newfiles;
    }

    private class downloadFileThread extends Thread {
        MediaFile file;
        boolean isDownloading = false;

        public downloadFileThread(MediaFile aFile) {
            file = aFile;
        }

        @Override
        public void run() {
            synchronized (this) {
                if (!isDownloading) {
                    download(file); // 从服务端监听命令
//                    List<String> newfiles = new ArrayList<String>();
//                    newfiles.add(file.getFileName());
//                    send_picture_to_GCS_by_http(newfiles);
                }
            }

        }
    }

    // 重置媒体管理器
    private void unsetMediaManager() {
        // 重置媒体管理器对象
        if (mMediaManager != null) {
            // 如果正在回放视频，则停止回放。
            mMediaManager.stop(null);
            // 如果正在下载媒体，则取消下载。
            mMediaManager.exitMediaDownloading();
        }

        // 相机退出媒体下载模式
        Camera camera = getCamera();
        if (camera != null) {
            camera.setMode(SettingsDefinitions.CameraMode.SHOOT_PHOTO, new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError djiError) {
                    if (djiError != null) {
                        showToast("修改相机模式失败!" + djiError.getDescription());
                    }
                }
            });
        }

    }

    private void send_picture_to_GCS_by_http(List<String> newfiles) {
        try {
            String url = "http://" + ipAddr + ":3000/image";
//            url = "http://"+ipAddr+":3000/image";
            Thread.sleep(5000);
            String buf = "";
            int whilenum = 0;
            String[] files = newfiles.toArray(new String[0]); //files里只有文件名，没有文件的绝对路径。
            int filesNum = files.length;
            for (int ifile = 0; ifile < filesNum; ifile++) {
                OkHttpClient client = new OkHttpClient();
                MultipartBody.Builder builder = new
                        MultipartBody.Builder().setType(MultipartBody.FORM);
                File file = new File(context.getExternalFilesDir(null) + "/media/" + files[ifile]);
                if (file != null) {
                    builder.addFormDataPart("file", file.getName(),
                            RequestBody.create(MediaType.parse("png"), file));
                    //添加其他参数
                    //builder.addFormDataPart("id", id);
                }
                MultipartBody multipartBody = builder.build();
                //构建请求
                final Request request = new Request.Builder()
                        .url(url)//请求地址
                        .post(multipartBody)//添加请求体参数
                        .build();
                //请求回调
                Call call = client.newCall(request);
                final int filenum = ifile;
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
//                        Log.e("TAG","上传失败"+e.getLocalizedMessage());
                        showToast("TAG " + "文件" + Integer.toString(filenum) + " 上传失败" + e.getLocalizedMessage());
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        final String responseStr = response.body().string();
//                        Log.e("TAG","上传成功"+responseStr);
                        showToast("TAG " + "文件" + Integer.toString(filenum) + " 上传成功" + responseStr);
                    }
                });
            }
        } catch (Exception ex) {
            // 键为null或使用json不支持的数字格式(NaN, infinities)
            throw new RuntimeException(ex);
        }

    }

    // 获得无人机的相机对象
    private Camera getCamera() {
        BaseProduct product = DJISDKManager.getInstance().getProduct();
        if (product != null && product.isConnected()) {
            return product.getCamera();
        }
        return null;
    }

    private void showToast(final String toastMsg) {
        for (UAVPictureUploadListener listener : listeners) {
            listener.onLog(toastMsg);
        }
    }

}
